#include "include/port/swei_log.h"
#include "include/swei_package.h"
#include "include/swei_location.h"
#include "global.h"

#include "FreeRTOS.h"
#include "queue.h"

#include "utils/utils_timer.h"
#include "service/include/swei_config.h"
#include "misc/misc_system.h"
#include "service/include/swei_login.h"
#include "mmgr/include/mmgr_wifi.h"

#define LOC_MAX_SIZE (128)
QueueHandle_t loc_queue = NULL;
loc_record_t  loc_rec = {0};

bool swei_location_queue_is_empty(void) 
{
    if(loc_queue != NULL) {
        return (pdFAIL == uxQueueMessagesWaiting(loc_queue));
    }        
    
    return true;
}


int32_t swei_location_queue_init(void)
{
    // 1. 队列创建
    if(NULL == loc_queue)
    {
        loc_queue = xQueueCreate(LOC_MAX_SIZE, sizeof(common_msg_st));
    }
    else
    {
        return 0;
    }

    // 2. 队列有效性检查
    if(NULL == loc_queue)
    {
        log_e("loc queue have not been created!\r\n");
        return -EIO;
    }

    return 0;
}

/**
 * @brief 从loc队列中获取消息   
 * @param  msg              My Param doc
 * @return int32_t 
 */
int32_t swei_location_pop(common_msg_st *msg)
{
    // 1. 队列创建
    if(swei_location_queue_init())
    {
        log_e("msg is NULL!\r\n");
        return -EIO;
    }

    // 2. msg数据指针检查
    if(NULL == msg){
        log_e("msg is NULL!\r\n");
        return -EIO;
    }

    // 3. 数据出队
    if(pdPASS != xQueueReceive(loc_queue, msg, 0)){
        return -EIO;
    }
    
    return 0;
}


static uint32_t forced_location_report_flag = 0;
void swei_location_set_force_report(uint8_t f_type) 
{
    if(f_type >= 32)
        return;

    forced_location_report_flag |= (1 << f_type);
}


bool swei_location_get_force_report_flag(uint8_t f_type) 
{
    if(f_type >= 32)
        return false;

    return forced_location_report_flag & (1 << f_type);
}

void swei_location_clear_force_report_flag(uint8_t f_type) 
{
    if(f_type >= 32)
        return;

    forced_location_report_flag &= ~(1 << f_type);
}



utils_time_t gps_upload_timer = {0};
/**
 * @brief 向loc队列中发送GPS信息事件
 * @param  msg              My Param doc
 * @return int32_t 
 */
int32_t swei_location_push_gps(void)
{
    common_msg_st msg = {0};
    int32_t ret = 0;
    int32_t sleep_time = 0;

    // 1. 队列创建
    if(swei_location_queue_init())
    {
        log_e("msg is NULL!\r\n");
        return -EIO;
    }

    // 2. 判断是否达到上报时间
    if(!swei_location_get_force_report_flag(REPORT_GPS)) {
        sleep_time = swei_config_rtp_intval_update(REPORT_GPS);
        if(0 == sleep_time) { /* 0 表示改模式下未配置上报 */
            return -EIO;
        }

        if(!utils_time_is_expired(&gps_upload_timer))
        {
            return -EIO;
        }
    } else {
        swei_location_clear_force_report_flag(REPORT_GPS);
    }

    // 3. 打包数据
    ret = swei_location_scan_gps_info(&msg, 0x00);
    if(ret < 0)
    {
        // log_e("location gps data packet failed!\r\n");
        return -EIO;
    }

    // 4. 消息入队
    if(pdPASS != xQueueSendToBack(loc_queue, &msg, 0))
    {
        // log_e("loc queue send failed!\r\n");
        return -EIO;
    }
    
    utils_time_countdown_ms(&gps_upload_timer, sleep_time * 1000);
    log_i(">>>> send gps info! <<<< \r\n");

    return 0;
}

utils_time_t gps_corner_timer = {0};
/**
 * @brief 向loc队列中发送GPS信息事件
 * @param  msg              My Param doc
 * @return int32_t 
 */
int32_t swei_location_push_corner_gps(void)
{
    common_msg_st msg = {0};
    int32_t ret = 0;

    if (!utils_time_is_expired(&gps_corner_timer)) {
        return 0;
    }

    // 3. 打包数据
    ret = swei_location_scan_gps_info(&msg, 0x02);
    if(ret < 0)
    {
        // log_e("location gps data packet failed!\r\n");
        return -EIO;
    }

    // 4. 消息入队
    if(pdPASS != xQueueSendToBack(loc_queue, &msg, 0))
    {
        // log_e("loc queue send failed!\r\n");
        return -EIO;
    }
    
    log_i(">>>> send gps corner info! <<<< \r\n");
    utils_time_countdown_ms(&gps_corner_timer, 1000);

    return 0;
}



utils_time_t lbs_upload_timer = {0};
/**
 * @brief 向loc队列中发送LBS 信息事件
 * @param  msg              My Param doc
 * @return int32_t 
 */
int32_t swei_location_push_lbs(void)
{
    common_msg_st msg = {0};
    int32_t ret = 0;
    int32_t sleep_time = 0;

    // 1. 队列创建
    if(swei_location_queue_init())
    {
        log_e("msg is NULL!\r\n");
        return -EIO;
    }

    // 2. 判断是否达到上报时间
    if(!swei_location_get_force_report_flag(REPORT_LBS)) {
        sleep_time = swei_config_rtp_intval_update(REPORT_LBS);
        if(0 == sleep_time) { /* 0 表示改模式下未配置上报 */
            return -EIO;
        }

        if(!utils_time_is_expired(&lbs_upload_timer))
        {
            return -EIO;
        }
    } else {
        swei_location_clear_force_report_flag(REPORT_LBS);
    }

    // 3. 打包数据
    ret = swei_location_scan_lbs_info(&msg);
    if(ret < 0)
    {
        // log_e("location lbs data packet failed!\r\n");
        return -EIO;
    }

    // 4. 消息入队
    if(pdPASS != xQueueSendToBack(loc_queue, &msg, 0))
    {
        // log_e("loc queue send failed!\r\n");
        return -EIO;
    }
    
    utils_time_countdown_ms(&lbs_upload_timer, sleep_time * 1000);
    log_i(">>>> send lbs info! <<<< \r\n");

    return 0;
}


utils_time_t wifi_upload_timer = {0};
/**
 * @brief 向loc队列中发送WIFISCAN 信息事件
 * @param  msg              My Param doc
 * @return int32_t 
 */
int32_t swei_location_push_wifi(void)
{
    common_msg_st msg = {0};
    int32_t ret = 0;
    int32_t sleep_time = 0;

    // 1. 队列创建
    if(swei_location_queue_init())
    {
        log_e("msg is NULL!\r\n");
        return -EIO;
    }

    // 2. 判断是否达到上报时间
    sleep_time = swei_config_rtp_intval_update(REPORT_WIFI);
    if(0 == sleep_time) { /* 0 表示改模式下未配置上报 */
        return -EIO;
    }

    if(!utils_time_is_expired(&wifi_upload_timer))
    {
        return -EIO;
    }
    
    mmgr_wifi_scan_start();
    // reset_misc_data_send_ok(1 << REPORT_WIFI);
     
    // 3. 打包数据
    ret = swei_location_scan_wifi_info(&msg);
    if(ret < 0)
    {
        // log_e("location wifi data packet failed!\r\n");
        return -EIO;
    }

    // 4. 消息入队
    if(pdPASS != xQueueSendToBack(loc_queue, &msg, 0))
    {
        // log_e("loc queue send failed!\r\n");
        return -EIO;
    }
    
    utils_time_countdown_ms(&wifi_upload_timer, sleep_time * 1000);
    log_i(">>>> send wifi info! <<<< \r\n");

    // set_misc_data_send_ok(1 << REPORT_WIFI);
    
    return 0;
}




/**
 * @brief 获取记录
 * @return loc_record_t* 
 */
loc_record_t *swei_location_get_record(void)
{
    return &loc_rec;
}

/**
 * @brief 获取队列状态
 * @return uint32_t 
 */
uint32_t swei_location_queue_size(void)
{
    if(NULL == loc_queue)
        return 0;
        
    return uxQueueMessagesWaiting(loc_queue);
}
